package common

import (
	"alertmanagerWebhook/config"
	"bytes"
	"encoding/json"
	"io"
	"net/http"

	"alertmanagerWebhook/global"
)

// SendNotification handles sending notifications to specified platforms.
func SendNotification(notification config.Notification, platform string) error {
	var webhookURL string
	message, err := TransformToMarkdown(notification)
	if err != nil {
		global.Logger.Errorf("error transforming notification: %v\n", err) // 记录错误
		return err                                                         // 返回实际的错误
	}
	switch platform {
	case "wechat":
		if !global.Config.QyWeChat.Enabled {
			global.Logger.Errorln("WeChat notifications are disabled.")
			return err
		}
		message = config.NewMessage(
			message.QywechatMessage.MarkdownFiring,
			message.QywechatMessage.MarkdownResolved,
			nil, nil,
		)
		global.Logger.Infof("messageWeChatFiringSize: %d\n", len(message.QywechatMessage.MarkdownFiring.Markdown.Content))
		global.Logger.Infof("messageWeChatResolvedSize: %d\n", len(message.QywechatMessage.MarkdownResolved.Markdown.Content))
		if len(message.QywechatMessage.MarkdownFiring.Markdown.Content) == 0 {
			global.Logger.Infoln("No firing alerts to send.")
		}
		if len(message.QywechatMessage.MarkdownResolved.Markdown.Content) == 0 {
			global.Logger.Infoln("No resolved alerts to send.")
		}
		//fmt.Printf("企业微信获得的告警信息长度总计:%d\n", len(message.QywechatMessage.MarkdownFiring.Markdown.Content))
		webhookURL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=" + global.Config.QyWeChat.QywechatKey
	case "dingding":
		if !global.Config.DingDing.Enabled {
			global.Logger.Errorln("Dingding notifications are disabled.")
			return err
		}
		message = config.NewMessage(
			nil, nil, message.DingdingMessage.DmarkdownFiring,
			message.DingdingMessage.DmarkdownResolved,
		)
		global.Logger.Infof("messageDDFiringSize: %d\n", len(message.DingdingMessage.DmarkdownFiring.Dmarkdown.Text))
		global.Logger.Infof("messageDDResolvedSize: %d\n", len(message.DingdingMessage.DmarkdownResolved.Dmarkdown.Text))
		if len(message.DingdingMessage.DmarkdownFiring.Dmarkdown.Text) == 0 {
			global.Logger.Infoln("No firing alerts to send.")
			return nil // No need to send, just exit
		}
		if len(message.DingdingMessage.DmarkdownResolved.Dmarkdown.Text) == 0 {
			global.Logger.Infoln("No resolved alerts to send.")
			return nil // No need to send, just exit
		}
		webhookURL = "https://oapi.dingtalk.com/robot/send?access_token=" + global.Config.DingDing.DingdingKey
	default:
		global.Logger.Errorf("unsupported platform: %s\n", platform)
		return err
	}

	// 只发送当前平台相关的告警信息
	var alertDetails []struct {
		markdown  interface{}
		alertType string
	}

	if platform == "wechat" {
		alertDetails = append(alertDetails, struct {
			markdown  interface{}
			alertType string
		}{
			message.QywechatMessage.MarkdownFiring, "firing",
		})
		if message.QywechatMessage.MarkdownResolved != nil {
			alertDetails = append(alertDetails, struct {
				markdown  interface{}
				alertType string
			}{
				message.QywechatMessage.MarkdownResolved, "resolved",
			})
		}
	} else if platform == "dingding" {
		alertDetails = append(alertDetails, struct {
			markdown  interface{}
			alertType string
		}{
			message.DingdingMessage.DmarkdownFiring, "firing",
		})
		if message.DingdingMessage.DmarkdownResolved != nil {
			alertDetails = append(alertDetails, struct {
				markdown  interface{}
				alertType string
			}{
				message.DingdingMessage.DmarkdownResolved, "resolved",
			})
		}
	}

	for _, detail := range alertDetails {
		if detail.markdown != nil {
			if err := sendSingleMessage(webhookURL, detail.markdown); err != nil {
				global.Logger.Errorf("Error sending message for %s: %v\n", detail.alertType, err)
			}
		}
	}

	return nil
}

// sendSingleMessage handles the actual sending for a single part of the message
func sendSingleMessage(webhookURL string, messageData interface{}) error {
	data, err := json.Marshal(messageData)
	if err != nil {
		global.Logger.Errorf("error marshalling message: %v\n", err)
		return err
	}

	if len(data) == 0 {
		global.Logger.Infoln("invalid request body: empty message")
		return err
	}
	req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(data))
	if err != nil {
		global.Logger.Errorf("error creating request: %v\n", err)
		return err
	}
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		global.Logger.Errorf("resp error sending request: %v\n", err)
		return err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		global.Logger.Errorf("error reading response body: %v\n", err)
		return err
	}

	var response map[string]interface{}
	if err = json.Unmarshal(body, &response); err != nil {
		global.Logger.Errorf("error unmarshalling response: %v\n", err)
		return err
	}

	if resp.StatusCode != http.StatusOK {
		global.Logger.Errorf("Non-OK HTTP status: %s, Response: %v\n", resp.Status, response)
		return nil
	}

	if errCode, ok := response["errcode"].(float64); ok && int(errCode) != 0 {
		global.Logger.Errorf("send alert message error: %d, Response: %v\n", int(errCode), response)
		return nil
	}

	return nil
}

// SendWeChatNotification is now a wrapper around SendNotification for WeChat
func SendWeChatNotification(notification config.Notification) error {
	return SendNotification(notification, "wechat")
}

// SendToDingding is now a wrapper around SendNotification for DingDing
func SendToDingding(notification config.Notification) error {
	return SendNotification(notification, "dingding")
}
